JavaScript30
第十五天的主要目標是學習利用 localStorage
在本地儲存的方法,
Github 檔案位置:15 - LocalStorage
網頁一開始的樣子如下,這個清單目前還沒有任何功能
可以先去看看 最後的成品
將程式的要求拆分步驟後,我們需要做的事情如下
初始的程式碼如下,主要就是整合了這半個月學到的種種知識,即可完成在畫面上動態新增清單
const addItems = document.querySelector('.add-items');
const itemsList = document.querySelector('.plates');
const items = [];
function addItem(e) {
e.preventDefault(); // 取消 DOM 的預設操作
const text = (this.querySelector('[name=item]')).value; // 抓取輸入框的值
const item = {
text,
done: false
};
items.push(item);
populateList(items, itemsList); // 將輸入的 item 輸出至網頁上
this.reset(); // 重置輸入框
}
function populateList(plates = [], platesList) {
platesList.innerHTML = plates.map((plate, i) => {
return `
<li>
<input type="checkbox" data-index=${i} id="item${i}" ${plate.done ? 'checked' : ''} />
<label for="item${i}">${plate.text}</label>
</li>
`;
}).join(''); // 消除 List 元素之間自動有的逗號
}
addItems.addEventListener('submit', addItem);
但目前的網頁只要刷新了資料就會不見,這裡我們會用到 Storage.setItem()
,這個函式可以將資料以 JSON 的格式(以JSON.stringify()
轉換)儲存在 F12 -> Application -> Local Storage 中,即使關閉網頁依舊存在
如此我們只要讀存在 Local Storage 中的資料就可以做到資料的儲存
const items = JSON.parse(localStorage.getItem('items')) || []; // 如果有本地端儲存的 items 變數則使用,否則為空
function addItem(e) {
//...
localStorage.setItem('items', JSON.stringify(items)); // 在本地端設置名為 'items' 的變數,並存入 JSON 後的 items
}
populateList(items, itemsList); // 如果有本地端儲存的 items 則先輸出到畫面
到此就完成了大部份的功能,在關閉網頁後已經可以儲存資料了
上次做 checkbox 的偵測時我們需要用 forEach
去幫所有 checkbox 做監聽
但我們其實可以在 HTML 就設定好,然後善用 target
中的 dataset.index
去代替這件事情
具體的執行邏輯就是在整份 itemsList
下 click
事件監聽,當觸發 click
事件後,可以發現 console.log(e.target.dataset.index)
吐出被點擊的那個 DOM 的 index,我們就可以利用這數值去做 item 的 done 轉換,並在轉換後丟進 localStorage
中
function toggleDone(e) {
console.log(e.target.dataset.index);
if (!e.target.matches('input')) return; // skip this unless it's an input
const el = e.target;
const index = el.dataset.index;
items[index].done = !items[index].done;
localStorage.setItem('items', JSON.stringify(items));
populateList(items, itemsList);
}
itemsList.addEventListener('click', toggleDone);
const addItems = document.querySelector('.add-items');
const itemsList = document.querySelector('.plates');
const items = JSON.parse(localStorage.getItem('items')) || []; // 如果有本地端儲存的 items 變數則使用,否則為空
function addItem(e) {
e.preventDefault(); // 取消 DOM 的預設操作
const text = (this.querySelector('[name=item]')).value; // 抓取輸入框的值
const item = {
text,
done: false
};
items.push(item);
populateList(items, itemsList); // 將輸入的 item 輸出至網頁上
localStorage.setItem('items', JSON.stringify(items)); // 在本地端設置名為 'items' 的變數,並存入 JSON 後的 items
this.reset(); // 重置輸入框
}
function populateList(plates = [], platesList) {
platesList.innerHTML = plates.map((plate, i) => {
return `
<li>
<input type="checkbox" data-index=${i} id="item${i}" ${plate.done ? 'checked' : ''} />
<label for="item${i}">${plate.text}</label>
</li>
`;
}).join(''); // 消除 List 元素之間自動有的逗號
}
function toggleDone(e) {
console.log(e.target.dataset.index);
if (!e.target.matches('input')) return; // skip this unless it's an input
const el = e.target;
const index = el.dataset.index;
items[index].done = !items[index].done;
localStorage.setItem('items', JSON.stringify(items));
populateList(items, itemsList);
}
addItems.addEventListener('submit', addItem);
itemsList.addEventListener('click', toggleDone);
populateList(items, itemsList); // 如果有本地端儲存的 items 則輸出到畫面
以上是第十五天的製作紀錄,如有錯誤或不足的地方還請多多指教 >.<
How LocalStorage and Event Delegation work. #JavaScript30 15/30
[ Alex 宅幹嘛 ] 深入淺出 Javascript30 快速導覽 | Day 15:LocalStorage
MDN Web Docs